package com.nt.thah.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.nt.thah.constant.SysCode;
import com.nt.thah.constant.WebConfig;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 微信授权工具类
 * @author: ls
 * @date: 2020/7/13 10:27
 */
@Component
@Slf4j
public class WxAuthUtil {

    @Resource
    private WebConfig webConfig;

    @Resource
    private RedisUtil redisUtil;

    private static final String Token = "lianshuai123";

    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * @Description: 校验微信签名
     * @author: ls
     * @Date: 2020/7/11 20:55
     */
    public boolean checkSignature(String signature, String timestamp, String nonce) throws NoSuchAlgorithmException {
        String[] strArr = new String[]{Token, timestamp, nonce};
        Arrays.sort(strArr);
        String str = strArr[0] + strArr[1] + strArr[2];
        String mySignature = getSignature(str);
        return mySignature.equals(signature);
    }

    /**
     * @Description: 获取签名
     * @author: ls
     * @Date: 2020/7/21 10:23
     */
    public String getSignature(String str) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
        messageDigest.update(str.getBytes());
        byte[] bytes = messageDigest.digest();
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (byte aByte : bytes) {
            buf.append(HEX_DIGITS[(aByte >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[aByte & 0x0f]);
        }
        return buf.toString();
    }

    /**
     * @Description: 获取全局的代理端accessToken
     * @author: ls
     * @Date: 2020/7/13 10:33
     */
    private String getGlobalAgentAccessToken() {
        String accessToken = redisUtil.get(SysCode.WX_AUTH_GLOBAL_ACCESS_TOKEN);
        if (!Strings.isNullOrEmpty(accessToken)) {
            return accessToken;
        }
        String sBuilder = "https://api.weixin.qq.com/cgi-bin/token" +
                "?grant_type=client_credential" +
                "&appid=" + webConfig.getAppId() +
                "&secret=" + webConfig.getAppSecret();
        JSONObject tokenJson = HttpClientUtils.httpGet(sBuilder, null);
        accessToken = tokenJson.getString("access_token");
        if (StringUtils.isBlank(accessToken)) {
            log.error("获取accessToken失败：{}", tokenJson);
        }
        redisUtil.set(SysCode.WX_AUTH_GLOBAL_ACCESS_TOKEN, accessToken, 110, TimeUnit.MINUTES);
        return accessToken;
    }

    /**
     * @Description: 获取用户基本信息(UnionID机制)
     * @author: ls
     * @Date: 2020/7/13 10:33
     */
    public JSONObject getUserBaseInfo(String openId) {
        String accessToken = getGlobalAgentAccessToken();
        String sBuilder = "https://api.weixin.qq.com/cgi-bin/user/info?" +
                "access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN";
        JSONObject jsonObject = HttpClientUtils.httpGet(sBuilder, null);
        if (StringUtils.isBlank(jsonObject.getString("subscribe"))) {
            log.error("获取用户基本信息(UnionID机制)失败：{}", jsonObject);
        }
        return jsonObject;
    }

    /**
     * @Description: 网页授权的accessToken
     * @author: ls
     * @Date: 2020/7/13 10:33
     */
    public JSONObject getAuthAccessToken(String code) {
        String sBuilder = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + webConfig.getAppId() +
                "&secret=" + webConfig.getAppSecret() +
                "&code=" + code +
                "&grant_type=authorization_code";
        JSONObject jsonObject = HttpClientUtils.httpGet(sBuilder, null);
        if (StringUtils.isBlank(jsonObject.getString("access_token"))) {
            log.error("获取网页授权的accessToken失败：{}", jsonObject);
        }
        return jsonObject;
    }

    /**
     * @Description: 获取网页授权的用户信息失败
     * @author: ls
     * @Date: 2020/7/13 10:33
     */
    public JSONObject getAuthUserInfo(String code, String accessToken, String openId) {
        String sBuilder = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=" + accessToken +
                "&openid=" + openId +
                "&code=" + code +
                "&lang=zh_CN";
        JSONObject jsonObject = HttpClientUtils.httpGet(sBuilder, null);
        if (StringUtils.isBlank(jsonObject.getString("openid"))) {
            log.error("获取网页授权的用户信息失败：{}", jsonObject);
        }
        return jsonObject;
    }

    /**
     * @Description: 根据openId推送消息
     * @author: ls
     * @Date: 2020/7/13 14:11
     */
    public void pushWxMsg(String openId, List<WxMpTemplateData> wxMpTemplateDataList, String templateId, String url) {
        String accessToken = getGlobalAgentAccessToken();
        String templateMsgUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
        // 1、发送模板消息接口
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openId)
                .templateId(templateId)
                .build();
        // 2、跳转的url链接
        if (StringUtils.isNotBlank(url)) {
            templateMessage.setUrl(url);
        }
        // 3、添加模板数据并发送
        templateMessage.setData(wxMpTemplateDataList);
        JSONObject jsonObject = HttpClientUtils.httpPost(templateMsgUrl, templateMessage.toJson(), null);
        if (jsonObject.getIntValue("errcode") != 0) {
            log.info("推送微信模板信息失败:{}", jsonObject);
        }
    }
}

